#include "pipe_stream.h"

#include <errno.h>
#include <fcntl.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/time.h>
#include <unistd.h>
#include <iostream>
#include <atomic>
#include "opencv2/core.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"

using namespace cv;
using namespace std;

typedef unsigned char byte;

void pipe_stop_all(Pipe_Stream *pipe){

    int count=0;
    int index[MAX_PLANE_COUNT]={0};
    for(int i=0;i<MAX_PLANE_COUNT;i++){
        if(pipe[i].get_status()==ps_runing){
            index[count]=i;
            count++;
        }
    }
    for(int i=0;i<count;i++){
        pipe[index[i]].stoping();
    }
    for(int i=0;i<count;i++){
        pipe[index[i]].wait_stoping();
    }
}


void Pipe_Stream::start(Capture *cap,struct drm_plane *plane,Pipe_Convert_Type type){
    printf("pipe start\r\n");
    Pipe_Stream_State now=get_status();
    if(now==ps_init){
        this->plane=plane;
        this->cap=cap;
        convert_type=type;
        switch (convert_type) {
        case nv12_nv12:
            pipeThread=new std::thread(&Pipe_Stream::stream_process_nv12_nv12,this);
            break;
        case nv12_rgb:
            pipeThread=new std::thread(&Pipe_Stream::stream_process_nv12_rgb,this);
            break;
        case yuyv_rgb:
            pipeThread=new std::thread(&Pipe_Stream::stream_process_yuyv_rgb,this);
            break;
        case rgb_nv12:
            pipeThread=new std::thread(&Pipe_Stream::stream_process_rgb_nv12,this);
            break;
        case rgb_rgb:
            pipeThread=new std::thread(&Pipe_Stream::stream_process_rgb_rgb,this);
            break;
        }
    }
    else if(now==ps_stoped){
        this->plane=plane;
        this->cap=cap;
        re_run();
    }
    else{
        fprintf(stderr,"pipe runing now\r\n");
    }
}


//normal
void RGB_to_NV12_intrinsic( byte* pRGB,byte* pNV12, int width, int height)
{
    const uint8x8_t u8_zero = vdup_n_u8(0);
    const uint8x8_t u8_16 = vdup_n_u8(16);
    const uint16x8_t u16_rounding = vdupq_n_u16(128);

    const int16x8_t s16_zero = vdupq_n_s16(0);
    const int8x8_t s8_rounding = vdup_n_s8(-128);
    const int16x8_t s16_rounding = vdupq_n_s16(128);

    byte* UVPtr = pNV12 + width * height;
    int pitch = width >> 4;

    for (int j = 0; j < height; ++j)
    {
        for (int i = 0; i < pitch; ++i)
        {
            // Load RGB 16 pixel
            uint8x16x3_t pixel_rgb = vld3q_u8(pRGB);

            uint8x8_t high_r = vget_high_u8(pixel_rgb.val[0]);
            uint8x8_t low_r = vget_low_u8(pixel_rgb.val[0]);
            uint8x8_t high_g = vget_high_u8(pixel_rgb.val[1]);
            uint8x8_t low_g = vget_low_u8(pixel_rgb.val[1]);
            uint8x8_t high_b = vget_high_u8(pixel_rgb.val[2]);
            uint8x8_t low_b = vget_low_u8(pixel_rgb.val[2]);

            // NOTE:
            // declaration may not appear after executable statement in block
            uint16x8_t high_y;
            uint16x8_t low_y;

            uint8x8_t scalar = vdup_n_u8(66);  // scalar = 66
            high_y = vmull_u8(high_r, scalar);  // Y = R * 66
            low_y = vmull_u8(low_r, scalar);

            scalar = vdup_n_u8(129);
            high_y = vmlal_u8(high_y, high_g, scalar);  // Y = Y + R*129
            low_y = vmlal_u8(low_y, low_g, scalar);

            scalar = vdup_n_u8(25);
            high_y = vmlal_u8(high_y, high_b, scalar);  // Y = Y + B*25
            low_y = vmlal_u8(low_y, low_b, scalar);

            high_y = vaddq_u16(high_y, u16_rounding);  // Y = Y + 128
            low_y = vaddq_u16(low_y, u16_rounding);

            uint8x8_t u8_low_y = vshrn_n_u16(low_y, 8);  // Y = Y >> 8
            uint8x8_t u8_high_y = vshrn_n_u16(high_y, 8);

            low_y = vaddl_u8(u8_low_y, u8_16);  // Y = Y + 16
            high_y = vaddl_u8(u8_high_y, u8_16);

            uint8x16_t pixel_y = vcombine_u8(vqmovn_u16(low_y), vqmovn_u16(high_y));

            // Store
            vst1q_u8(pNV12, pixel_y);

            if (j % 2 == 0)
            {
                uint8x8x2_t mix_r = vuzp_u8(low_r, high_r);
                uint8x8x2_t mix_g = vuzp_u8(low_g, high_g);
                uint8x8x2_t mix_b = vuzp_u8(low_b, high_b);

                int16x8_t signed_r = vreinterpretq_s16_u16(vaddl_u8(mix_r.val[0], u8_zero));
                int16x8_t signed_g = vreinterpretq_s16_u16(vaddl_u8(mix_g.val[0], u8_zero));
                int16x8_t signed_b = vreinterpretq_s16_u16(vaddl_u8(mix_b.val[0], u8_zero));

                int16x8_t signed_u;
                int16x8_t signed_v;

                int16x8_t signed_scalar = vdupq_n_s16(-38);
                signed_u = vmulq_s16(signed_r, signed_scalar);

                signed_scalar = vdupq_n_s16(112);
                signed_v = vmulq_s16(signed_r, signed_scalar);

                signed_scalar = vdupq_n_s16(-74);
                signed_u = vmlaq_s16(signed_u, signed_g, signed_scalar);

                signed_scalar = vdupq_n_s16(-94);
                signed_v = vmlaq_s16(signed_v, signed_g, signed_scalar);

                signed_scalar = vdupq_n_s16(112);
                signed_u = vmlaq_s16(signed_u, signed_b, signed_scalar);

                signed_scalar = vdupq_n_s16(-18);
                signed_v = vmlaq_s16(signed_v, signed_b, signed_scalar);

                signed_u = vaddq_s16(signed_u, s16_rounding);
                signed_v = vaddq_s16(signed_v, s16_rounding);

                int8x8_t s8_u = vshrn_n_s16(signed_u, 8);
                int8x8_t s8_v = vshrn_n_s16(signed_v, 8);

                signed_u = vsubl_s8(s8_u, s8_rounding);
                signed_v = vsubl_s8(s8_v, s8_rounding);

                signed_u = vmaxq_s16(signed_u, s16_zero);
                signed_v = vmaxq_s16(signed_v, s16_zero);

                uint16x8_t unsigned_u = vreinterpretq_u16_s16(signed_u);
                uint16x8_t unsigned_v = vreinterpretq_u16_s16(signed_v);

                uint8x8x2_t result;
                result.val[0] = vqmovn_u16(unsigned_u);
                result.val[1] = vqmovn_u16(unsigned_v);

                vst2_u8(UVPtr, result);
                UVPtr += 16;
            }

            pRGB += 3*16;
            pNV12 += 16;
        }
    }
}
//color erro
void NV12toRGB_Intrinsic(unsigned char* pNV12, unsigned char* pRGB, int width, int height)
{
//    printf("[NEON] YUV420SP to RGB24\n");
    const uint8x8_t u8_zero = vdup_n_u8(0);
    const int16x8_t s16_zero = vdupq_n_s16(0);
    const int16x8_t s16_128 = vdupq_n_s16(-128);

    int frameSize = width * height;

    unsigned char* pUV_head = pNV12 + frameSize;
    unsigned char* pUV;

    int pitch = width >> 3;

    for (int row = 0; row < height; ++row)
    {
        if(row > 0 && row % 2 == 0){
            pUV_head += width;
        }
        pUV = pUV_head;

        for (int i = 0; i < pitch; ++i)
        {
            uint16x4_t pixel_uv = vld1_u16((unsigned short *)pUV);  // [UV][UV][UV][UV]
            uint8x8_t pixel_y = vld1_u8(pNV12);  // [Y][Y][Y][Y][Y][Y][Y][Y]

            uint16x4_t u16x4_u = vsri_n_u16(pixel_uv, pixel_uv, 8);  // [UU][UU][UU][UU]
            uint8x8_t pixel_u = vreinterpret_u8_u16(u16x4_u);  // [U][U][U][U][U][U][U][U]

            uint16x4_t u16x4_v = vsli_n_u16(pixel_uv, pixel_uv, 8);  // [VV][VV][VV][VV]
            uint8x8_t pixel_v = vreinterpret_u8_u16(u16x4_v);  // [V][V][V][V][V][V][V][V]

            int16x8_t signed_y = vreinterpretq_s16_u16(vaddl_u8(pixel_y, u8_zero));
            int16x8_t signed_u = vreinterpretq_s16_u16(vaddl_u8(pixel_u, u8_zero));
            int16x8_t signed_v = vreinterpretq_s16_u16(vaddl_u8(pixel_v, u8_zero));

            signed_u = vaddq_s16(signed_u, s16_128);
            signed_v = vaddq_s16(signed_v, s16_128);

            int16x8_t signed_scaler = vdupq_n_s16(88);
            int16x8_t signed_g1 = vmulq_s16(signed_u, signed_scaler);

            signed_scaler = vdupq_n_s16(184);
            int16x8_t signed_g2 = vmulq_s16(signed_v, signed_scaler);

            signed_scaler = vdupq_n_s16(360);
            int16x8_t signed_r = vmulq_s16(signed_v, signed_scaler);

            signed_scaler = vdupq_n_s16(455);
            int16x8_t signed_b = vmulq_s16(signed_u, signed_scaler);

            int16x8_t signed_g = vaddq_s16(signed_g1, signed_g2);

            signed_r = vshrq_n_s16(signed_r, 8);
            signed_b = vshrq_n_s16(signed_b, 8);
            signed_g = vshrq_n_s16(signed_g, 8);

            signed_r = vaddq_s16(signed_y, signed_r);
            signed_b = vaddq_s16(signed_y, signed_b);
            signed_g = vsubq_s16(signed_y, signed_g);

            signed_r = vmaxq_s16(signed_r, s16_zero);
            signed_b = vmaxq_s16(signed_b, s16_zero);
            signed_g = vmaxq_s16(signed_g, s16_zero);

            uint16x8_t unsigned_r = vreinterpretq_u16_s16(signed_r);
            uint16x8_t unsigned_b = vreinterpretq_u16_s16(signed_b);
            uint16x8_t unsigned_g = vreinterpretq_u16_s16(signed_g);

            uint8x8_t u8_r = vqmovn_u16(unsigned_r);
            uint8x8_t u8_b = vqmovn_u16(unsigned_b);
            uint8x8_t u8_g = vqmovn_u16(unsigned_g);

            uint8x8x3_t result;
            result.val[0] = u8_r;
            result.val[2] = u8_b;
            result.val[1] = u8_g;
            vst3_u8(pRGB, result);

            pRGB += 8*3;
            pNV12 += 8;
            pUV += 8;
        }
    }

}
//normal
void RGBtoNV12(byte* pRGB,byte* pNV12, int width, int height)
{
    int frameSize = width * height;
    int yIndex = 0;
    int uvIndex = frameSize;

    int R, G, B, Y, U, V;
    int index = 0;
    for (int j = 0; j < height; j++)
    {
        for (int i = 0; i < width; i++)
        {
            R = pRGB[index++];
            G = pRGB[index++];
            B = pRGB[index++];

            Y = ((66 * R + 129 * G + 25 * B + 128) >> 8) + 16;
            U = ((-38 * R - 74 * G + 112 * B + 128) >> 8) + 128;
            V = ((112 * R - 94 * G - 18 * B + 128) >> 8) + 128;

            // NV12  YYYYYYYY UVUV
            // NV21  YYYYYYYY VUVU
            pNV12[yIndex++] = (byte)((Y < 0) ? 0 : ((Y > 255) ? 255 : Y));
            if (j % 2 == 0 && index % 2 == 0)
            {
                pNV12[uvIndex++] = (byte)((U < 0) ? 0 : ((U > 255) ? 255 : U));
                pNV12[uvIndex++] = (byte)((V < 0) ? 0 : ((V > 255) ? 255 : V));
            }
        }
    }
}
//normal
void NV12toRGB(unsigned char* nv12, unsigned char* rgb, int width, int height)
{
    int frameSize = width * height;
    int yIndex = 0;
    int uvIndex = frameSize;

    int R, G, B, Y, U, V;
    int rgbIndex = 0;

    for (int j = 0; j < height; j++)
    {
        if(j % 2 == 0){
            uvIndex = frameSize + (j/2)*width;
        }

        for (int i = 0; i < width; i++)
        {
            Y = nv12[yIndex];
            U = nv12[uvIndex];
            V = nv12[uvIndex+1];

            R = Y + ((360 * (V - 128))>>8);
            G = Y - (( ( 88 * (U - 128)  + 184 * (V - 128)) )>>8);
            B = Y + ((455 * (U - 128))>>8);

            rgb[rgbIndex++] = (unsigned char)((R < 0) ? 0 : ((R > 255) ? 255 : R));
            rgb[rgbIndex++] = (unsigned char)((G < 0) ? 0 : ((G > 255) ? 255 : G));
            rgb[rgbIndex++] = (unsigned char)((B < 0) ? 0 : ((B > 255) ? 255 : B));

            yIndex++;
            if(i % 2 == 0){
                uvIndex += 2;
            }
        }
    }
}

void Pipe_Stream :: stream_process_nv12_nv12(){
    Pipe_Stream *pipe;
    struct timeval last={0,0},current={0,0};
      double fps = 0;
      int count=0;
    byte buffer[1280*720*3];
    bool already_run_flag=false;

    set_status(ps_runing);
    while(true){
        if(get_status()==ps_runing){
            if(plane->bo==NULL){
                fprintf(stderr,"plane id :%d ->bo is NULL erro,plane not init",plane->plane_id);
                sleep(1);
                continue;
            }
            Frame frame=cap->getLastFrame();
            if(frame.data==nullptr){
                fprintf(stderr,"v4l2 capture  erro frame.data is null ");
                sleep(1);
                continue;
            }
            gettimeofday(&current,NULL);
            //current.tv_sec * 1000 + current.tv_usec / 1000;
            fps = (current.tv_sec - last.tv_sec) * 1000000
                + current.tv_usec - last.tv_usec;
            fps = fps ? 1000000.0 / fps : 0.0;

            cv::Mat nv12(frame.height * frame.channels / frame.split, frame.width, CV_8UC1);
    //        cv::Mat bgr(frame.height, frame.width, CV_8UC3);
            Mat bgr;
            memcpy(nv12.data, frame.data, frame.width * frame.height * frame.channels / frame.split);
            cv::cvtColor(nv12,bgr,CV_YUV2RGB_NV12);
            cv::resize(bgr,bgr,Size(plane->w,plane->h));
            RGB_to_NV12_intrinsic(bgr.data,buffer,plane->w,plane->h);
//            plane_cpy(plane,buffer,plane->w*plane->h*3/2);
            plane_double_fb_cpy(plane,buffer,plane->w*plane->h*3/2);
        //    std::cout<<bgr.size<<std::endl;
            usleep(20*1000);
            count++;
            if(count%60==0){
    //        printf("video plane:%d :fps%f\n",plane->plane_id,fps);
    //        fflush(stdout);
            }
            last=current;
            already_run_flag=true;
        }
        else{
            if(already_run_flag){
                already_run_flag=false;
                set_status(ps_stoped);
            }
            usleep(100*1000);
        }
    }
    printf("pipe critical erro");
//    return bgr;
    return;
}
void Pipe_Stream :: stream_process_nv12_rgb(){
    Pipe_Stream *pipe;
    struct timeval last={0,0},current={0,0};
      double fps = 0;
      int count=0;
    byte buffer[1280*720*3];
    bool already_run_flag=false;

    set_status(ps_runing);
    while(true){
        if(get_status()==ps_runing){
            if(plane->bo==NULL){
                fprintf(stderr,"plane id :%d ->bo is NULL erro,plane not init",plane->plane_id);
                sleep(1);
                continue;
            }
            Frame frame=cap->getLastFrame();
            if(frame.data==nullptr){
                fprintf(stderr,"v4l2 capture  erro frame.data is null ");
                sleep(1);
                continue;
            }

            gettimeofday(&current,NULL);
            //current.tv_sec * 1000 + current.tv_usec / 1000;
            fps = (current.tv_sec - last.tv_sec) * 1000000
                + current.tv_usec - last.tv_usec;
            fps = fps ? 1000000.0 / fps : 0.0;

            cv::Mat nv12(frame.height * frame.channels / frame.split, frame.width, CV_8UC1);
    //        cv::Mat bgr(frame.height, frame.width, CV_8UC3);
            Mat bgr;
            memcpy(nv12.data, frame.data, frame.width * frame.height * frame.channels / frame.split);
            cv::cvtColor(nv12,bgr,CV_YUV2RGB_NV12);
//            cv::cvtColor(nv12,bgr,CV_YUV2BGR_NV12);
            cv::resize(bgr,bgr,Size(plane->w,plane->h));
    //        RGB_to_NV12_intrinsic(bgr.data,buffer,plane->w,plane->h);
//            plane_cpy(plane,bgr.data,bgr.cols*bgr.rows*bgr.elemSize());
            plane_double_fb_cpy(plane,bgr.data,bgr.cols*bgr.rows*bgr.elemSize());
        //    std::cout<<bgr.size<<std::endl;
            usleep(20*1000);
            count++;
            if(count%60==0){
//            printf("video plane:%d :fps%f\n",plane->plane_id,fps);
    //        fflush(stdout);
            }
            last=current;
            already_run_flag=true;
        }
        else{
            if(already_run_flag){
                already_run_flag=false;
                set_status(ps_stoped);
            }
            usleep(100*1000);
        }
    }
    printf("pipe critical erro");
//    return bgr;
    return;
}
void Pipe_Stream :: stream_process_yuyv_rgb(){
    Pipe_Stream *pipe;
    struct timeval last={0,0},current={0,0};
      double fps = 0;
      int count=0;
    byte buffer[1280*720*3];
    bool already_run_flag=false;

    set_status(ps_runing);
    while(true){
        if(get_status()==ps_runing){
            if(plane->bo==NULL){
                fprintf(stderr,"plane id :%d ->bo is NULL erro,plane not init",plane->plane_id);
                sleep(1);
                continue;
            }
            Frame frame=cap->getLastFrame();
            if(frame.data==nullptr){
                fprintf(stderr,"v4l2 capture  erro frame.data is null ");
                sleep(1);
                continue;
            }

            gettimeofday(&current,NULL);
            //current.tv_sec * 1000 + current.tv_usec / 1000;
            fps = (current.tv_sec - last.tv_sec) * 1000000
                + current.tv_usec - last.tv_usec;
            fps = fps ? 1000000.0 / fps : 0.0;

            cv::Mat yuyv(frame.height, frame.width, CV_8UC2);
    //        cv::Mat bgr(frame.height, frame.width, CV_8UC3);
            Mat bgr;
            memcpy(yuyv.data, frame.data, frame.width * frame.height * frame.channels / frame.split);
//            cv::cvtColor(yuyv,bgr,CV_YUV2RGB_YUYV);
            cv::cvtColor(yuyv,bgr,CV_YUV2BGR_YUYV);
            cv::resize(bgr,bgr,Size(plane->w,plane->h));
    //        RGB_to_NV12_intrinsic(bgr.data,buffer,plane->w,plane->h);
//            plane_cpy(plane,bgr.data,bgr.cols*bgr.rows*bgr.elemSize());
            plane_double_fb_cpy(plane,bgr.data,bgr.cols*bgr.rows*bgr.elemSize());
        //    std::cout<<bgr.size<<std::endl;
            usleep(40*1000);
            count++;
            if(count%60==0){
            printf("video plane:%d :fps%f\n",plane->plane_id,fps);
    //        fflush(stdout);
            }
            last=current;
            already_run_flag=true;
        }
        else{
            if(already_run_flag){
                already_run_flag=false;
                set_status(ps_stoped);
            }
            usleep(100*1000);
        }
    }
    printf("pipe critical erro");
//    return bgr;
    return;
}
void Pipe_Stream :: stream_process_rgb_rgb(){
    Pipe_Stream *pipe;
    struct timeval last={0,0},current={0,0};
      double fps = 0;
      int count=0;
    byte buffer[1280*720*3];
    bool already_run_flag=false;

    set_status(ps_runing);
    while(true){
        if(get_status()==ps_runing){
            if(plane->bo==NULL){
                fprintf(stderr,"plane id :%d ->bo is NULL erro,plane not init",plane->plane_id);
                sleep(1);
                continue;
            }
            Frame frame=cap->getLastFrame();
            if(frame.data==nullptr){
                fprintf(stderr,"v4l2 capture  erro frame.data is null ");
                sleep(1);
                continue;
            }

            gettimeofday(&current,NULL);
            //current.tv_sec * 1000 + current.tv_usec / 1000;
            fps = (current.tv_sec - last.tv_sec) * 1000000
                + current.tv_usec - last.tv_usec;
            fps = fps ? 1000000.0 / fps : 0.0;

    //        cv::Mat nv12(frame.height * frame.channels / frame.split, frame.width, CV_8UC1);
            cv::Mat bgr(frame.height, frame.width, CV_8UC3);
            memcpy(bgr.data, frame.data, frame.width * frame.height * frame.channels / frame.split);
            cv::Mat bgr1;
            cv::resize(bgr,bgr1,Size(plane->w,plane->h));

    //        RGB_to_NV12_intrinsic(bgr1.data,buffer,plane->w,plane->h);
    //        RGBtoNV12(bgr1.data,buffer,plane->w,plane->h);
    //        cv::cvtColor(bgr, nv12, CV_RGB2YUV_I420);
    //        plane_cpy(&plane[plane_id],nv12.data);
//            plane_cpy(plane,bgr1.data,bgr1.cols*bgr1.rows*bgr1.elemSize());
            plane_double_fb_cpy(plane,bgr1.data,bgr1.cols*bgr1.rows*bgr1.elemSize());
        //    std::cout<<bgr.size<<std::endl;
            usleep(20*1000);

            count++;
            if(count%60==0){
//            printf("video plane:%d :fps%f\n",plane->plane_id,fps);
    //        fflush(stdout);
            }
            last=current;
            already_run_flag=true;
        }
        else{
            if(already_run_flag){
                already_run_flag=false;
                set_status(ps_stoped);
            }
            usleep(100*1000);
        }
    }
    printf("pipe critical erro");
//    return bgr;
    return;
}

void Pipe_Stream :: stream_process_rgb_nv12(){
    Pipe_Stream *pipe;
    struct timeval last={0,0},current={0,0};
      double fps = 0;
      int count=0;
    byte buffer[1280*720*3];
    bool already_run_flag=false;

    set_status(ps_runing);
    while(true){
        if(get_status()==ps_runing){
            if(plane->bo==NULL){
                fprintf(stderr,"plane id :%d ->bo is NULL erro,plane not init",plane->plane_id);
                sleep(1);
                continue;
            }
            Frame frame =cap->getLastFrame();
            if(frame.data==nullptr){
                fprintf(stderr,"v4l2 capture  erro frame.data is null ");
                sleep(1);
                continue;
            }

            gettimeofday(&current,NULL);
            //current.tv_sec * 1000 + current.tv_usec / 1000;
            fps = (current.tv_sec - last.tv_sec) * 1000000
                + current.tv_usec - last.tv_usec;
            fps = fps ? 1000000.0 / fps : 0.0;

    //        cv::Mat nv12(frame.height * frame.channels / frame.split, frame.width, CV_8UC1);
            cv::Mat bgr(frame.height, frame.width, CV_8UC3);
            memcpy(bgr.data, frame.data, frame.width * frame.height * frame.channels / frame.split);
            cv::Mat bgr1;
            cv::resize(bgr,bgr1,Size(plane->w,plane->h));

            RGB_to_NV12_intrinsic(bgr1.data,buffer,plane->w,plane->h);
//            plane_cpy(plane,buffer,plane->w*plane->h*3/2);
            plane_double_fb_cpy(plane,buffer,plane->w*plane->h*3/2);
        //    std::cout<<bgr.size<<std::endl;
            usleep(20*1000);

            count++;
            if(count%60==0){
    //        printf("video plane:%d :fps%f\n",plane->plane_id,fps);
    //        fflush(stdout);
            }
            last=current;
            already_run_flag=true;
        }
        else{
            if(already_run_flag){
                already_run_flag=false;
                set_status(ps_stoped);
            }
            usleep(100*1000);
        }
    }
    printf("pipe critical erro");
//    return bgr;
    return;
}











